#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Purpose: Common function used for the exporters
# Created: 03/31/2010
# $Id $
# Copyright (c) 2008,2009 by University College London
# Authors:
#  Didrik Pinte <dpinte@dipole-consulting.com>
#
# This program is free software under the GPL (>=v2)
# Read the file COPYING coming with HydroPlatform for details.

import types
import numpy

from sqlalchemy import and_

from hydroplatform.model import network as nt
from hydroplatform.model import fields as fd

def get_object_name(network_object):
    """Return the object name to be written to the file.
    
    Nodes output the node name. Links outputs "from_name.to_name" using the
    starting and ending node name.
    """
    if isinstance(network_object, nt.Node):
        return network_object.name
    elif isinstance(network_object, nt.Link) :
        return "%s.%s" % (network_object.start.name, 
                          network_object.end.name)
    
def get_field(nobject, field, session):
    """
    Return the value for the given object and field            
    """
    if isinstance(nobject, nt.Node):
        dbtable = nt.NodeValue
        key_id = dbtable.node_id
    elif isinstance(nobject, nt.Link):
        dbtable = nt.LinkValue
        key_id = nt.LinkValue.link_id
    return session.query(dbtable).filter( \
            and_(dbtable.attribute_id == field.id, \
                 key_id == nobject.id)).first() 


def get_objectfield(objecttype, fieldname, session):
    """
    Returns the Field object associated with the fieldname for the given 
    objecttype
    
    FIXME : should add some caching
    """
    if isinstance(objecttype, nt.NodeType):
        search = nt.NodeField
        ftype = search.node_type_id
    elif isinstance(objecttype, nt.LinkType):
        search = nt.LinkField
        ftype = search.link_type_id
    else:
        raise Exception("Unknown type")
    
    field = session.query(search).filter(\
        and_(search.name == fieldname, \
             ftype == objecttype.id)).first()
    return field


def get_value(obj, field, session, formatted=True):
    """
    Returns the value of the field for the given fieldname and obj.
    Returns None if value does not exist
    """
    if isinstance(field, types.StringTypes):
        field = get_objectfield(obj.type, field, session)
    
    if field is None:
        message = "No field named %s for object type %s" % \
                      (field, obj.type.name)
        return None
    
    fval = obj.getFieldValue(session, field)
    if fval is None:
        return None
    elif fval.value is None:
        return None
    else:
        if formatted is False:
            return fval.value
        try:
            format = field.attribute_type.format            
        except AttributeError:
            # should mean there is no format attribute
            return fval.value

        if isinstance(fval.value, numpy.ndarray):
            return fval.value
        
        if format == "integer":
            if isinstance(fval.value, list):
                try:
                    return int(fval.value[0])
                except IndexError:
                    return None
            return int(fval.value)
        elif format == "binary":
            return "%x" % fval.value
        elif format == "float":
            return fval.value
        else:
            return fval.value


if __name__=='__main__':
    unittest.main()